<script setup lang="tsx">
// eslint-disable-next-line @typescript-eslint/no-unused-vars
import { reactive, watch } from 'vue';
import { useForm, usePagination } from '@sa/alova/client';
import { NButton, NPopconfirm } from 'naive-ui';
import { useNaiveForm } from '@/hooks/common/form';
import { $t } from '@/locales';
import {
  addRoleUser,
  deleteByRole,
  deleteByUser,
  deleteByUsers,
  paginateRoleUser,
  updateRoleUser
} from '@/service/api/manage';
import useTableOperate from '@/hooks/common/table/table-operate';
import useCheckedColumns from '@/hooks/common/table/table-columns';
import PorDictTag from '@/components/_builtin/por-dict-tag/index.vue';

defineOptions({
  name: 'UserDrawer'
});

interface Props {
  /** the edit row data */
  rowData?: Api.Row | null;
}

const props = defineProps<Props>();

interface Emits {
  (e: 'submitted'): void;
}

const emit = defineEmits<Emits>();

const visible = defineModel<boolean>('visible', {
  default: false
});

const userId = defineModel<number>();

const { formRef } = useNaiveForm();

const {
  loading: submitting,
  reset,
  send: submit,
  form: model,
  updateForm
} = useForm(formData => updateRoleUser(formData), {
  initialForm: {
    roleId: 0,
    roleName: '',
    userList: []
  } as Api.Manage.RoleUser,
  resetAfterSubmitting: true
});

function closeDrawer() {
  visible.value = false;
}

async function handleSubmit() {
  // request
  await submit();

  window.$message?.success('更新成功');
  closeDrawer();
  emit('submitted');
}

const searchParams = reactive({
  // if you want to use the searchParams in Form, you need to define the following properties, and the value is null
  // the value can not be undefined, otherwise the property in Form will not be reactive
  roleId: null
} as Api.Manage.RoleUser);
const { loading, data, refresh, reload, page, pageSize, pageCount, remove } = usePagination(
  (pageNum, size) =>
    paginateRoleUser({
      ...searchParams,
      pageNumber: pageNum,
      pageSize: size
    }),
  {
    data: ({ records }) => records,
    total: ({ total }) => total,

    // trigger reload when states in `searchParams` changed
    watchingStates: [searchParams],

    // debounce of `searchParams`
    debounce: [500]
  }
);

const { handleDelete, handleBatchDelete, checkedRowKeys, deleting } = useTableOperate(data, {
  async delete(row) {
    await deleteByUser(row.id as number);
    remove(row);
  },
  async batchDelete(rows) {
    await deleteByUsers(rows.map(({ id }) => id as number));
    remove(...rows);
  }
});

const { columnChecks, columns } = useCheckedColumns<typeof paginateRoleUser>(() => [
  {
    type: 'selection',
    align: 'center',
    width: 10
  },
  {
    key: 'userName',
    title: $t('page.manage.user.userName'),
    align: 'center',
    width: 80
  },
  {
    key: 'nickName',
    title: $t('page.manage.user.nickName'),
    align: 'center',
    width: 80
  },
  {
    key: 'status',
    title: '状态',
    align: 'center',
    width: 20,
    render: row => {
      if (!row.status) {
        return null;
      }

      return <PorDictTag dict-code="common_status" value={row.status} />;
    }
  },
  {
    key: 'phone',
    title: $t('page.manage.user.userPhone'),
    align: 'center',
    width: 80
  },
  {
    key: 'email',
    title: $t('page.manage.user.userEmail'),
    align: 'center',
    width: 100
  },

  {
    key: 'operate',
    title: $t('common.operate'),
    align: 'center',
    width: 40,
    fixed: 'right',
    render: row => (
      <div class="flex-center gap-8px">
        <NPopconfirm
          onPositiveClick={() => handleDelete(row.id)}
          positiveButtonProps={{
            loading: deleting.value
          }}
        >
          {{
            default: () => $t('common.confirmDelete'),
            trigger: () => (
              <NButton type="error" ghost size="small">
                {$t('common.delete')}
              </NButton>
            )
          }}
        </NPopconfirm>
      </div>
    )
  }
]);

function handleInitModel() {
  if (props.rowData && props.rowData.id) {
    model.value.roleName = props.rowData.name;
    model.value.roleId = props.rowData.id as number;
    updateForm(model.value);

    searchParams.roleId = props.rowData.id as number;
  } else {
    reset();
  }
}

watch(visible, () => {
  if (visible.value) {
    handleInitModel();
  } else {
    userId.value = undefined;
    reset();
  }
});

async function handleClearUser() {
  if (model.value.roleId) {
    await deleteByRole(model.value.roleId);

    reload();
  }
}

function handleUserSelect(value: number) {
  userId.value = value;
}

async function handleAddUser() {
  if (model.value.roleId && userId.value) {
    await addRoleUser(model.value.roleId, userId.value);

    reload();
  }
}
</script>

<template>
  <NDrawer v-model:show="visible" display-directive="show" :width="720">
    <NDrawerContent title="角色用户" :native-scrollbar="false" closable>
      <NForm ref="formRef" :model="model">
        <NFormItem :label="$t('page.manage.role.roleName')" path="name">
          <NInput v-model:value="model.roleName" :placeholder="$t('page.manage.role.form.roleName')" disabled />
        </NFormItem>
      </NForm>
      <NCard title="用户列表" :bordered="true" size="small">
        <template #header-extra>
          <NSpace>
            <PorSelect
              v-model:value="userId"
              placeholder="请选择需要添加的用户"
              url="/account/list"
              label-field="userName"
              value-field="id"
              value-to-number
              filterable
              class="user-select"
              size="small"
              @change="handleUserSelect"
            ></PorSelect>
            <TableHeaderOperation
              v-model:columns="columnChecks"
              :disabled-delete="checkedRowKeys.length === 0"
              :loading="loading"
              :setting-btn="false"
              @delete="handleBatchDelete"
              @refresh="refresh"
              @add="handleAddUser"
            />
          </NSpace>
        </template>
        <NDataTable
          v-model:checked-row-keys="checkedRowKeys"
          :columns="columns"
          :data="data"
          size="small"
          :scroll-x="962"
          :loading="loading"
          remote
          :row-key="row => row.id"
          :pagination="{
            page,
            pageSize,
            showSizePicker: true,
            pageCount,
            pageSizes: [10, 15, 20, 25, 30],
            onUpdatePage(value) {
              page = value;
            },
            onUpdatePageSize(value) {
              pageSize = value;
            }
          }"
        />
      </NCard>
      <template #footer>
        <NGrid :x-gap="12" :cols="2" layout-shift-disabled>
          <NGi>
            <NSpace :size="16" justify="start">
              <NButton type="error" class="drawer-footer-left" @click="handleClearUser">清空用户</NButton>
            </NSpace>
          </NGi>
          <NGi>
            <NSpace :size="16" justify="end">
              <NButton @click="closeDrawer">取消</NButton>
              <NButton type="primary" :loading="submitting" @click="handleSubmit">确认</NButton>
            </NSpace>
          </NGi>
        </NGrid>
      </template>
    </NDrawerContent>
  </NDrawer>
</template>

<style scoped>
.user-select {
  width: 200px;
}
</style>
